package work.gac.unbind;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.http.HttpRequest;
import cn.hutool.http.HttpResponse;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import core.encoder.lianwei.PIIDataAESEncoder;
import core.util.ConcurrentUtil;
import core.util.TransformCsvData;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;

import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

/**
 * @author Gong.Yang
 */
@Slf4j
public class Demo {
    private static final String storeCode = "gac";
    private static final String token = "Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJzdWIiOiJtYW5hZ2VyIiwiY2xpZW50VHlwZSI6InVzZXIiLCJ0ZW5hbnRJZCI6ImxvcmVhbCIsImV4cCI6MTY5MDUzNzg5NiwianRpIjoiM2RiTnU0bjh0WEtHWEhnZmE0WnhGSCJ9.OHfUsQizM_L0Y3aRFf7hrr-thS0KW9XaC-DuiYTd2dAegXHAOR0X5AAnCjiJ9v9Ld6hWLuxUU6kuxystA2U94Q";

    //文件
    private final static String prefix = "E:\\work-records\\Apple\\l-会员解绑\\2023-07-28";
    private static final String file = prefix + ".csv";
    private static final String out = prefix + "Out\\";
    private static final String empty = out + "empty.json";//三方卡号和手机号都没找到
    private static final String hit = out + "hit.json";//将要解绑和删除的用户ID
    private static final String unbindingErr = out + "unbindingErr.json";//解绑失败的
    private static final String deleteErr = out + "deleteErr.json";//删除失败的
    private static final String codeMap = out + "codeMap.json";//删除失败的


    //地址
    private static final String baseUrl = "https://socialcrm-admin-api.giorgioarmanibeauty.cn";
    private static final String getInfoUrlByThCode = baseUrl + "/gateway/api/member-manage/store/"+storeCode+"/customer_info_data?page=0&size=10&expression=basicInfo.thirdCode+eq+" + "%s" + "&sort=basicInfo.registerTime,desc";
    private static final String getInfoByPhone = baseUrl + "/gateway/api/member-manage/store/"+storeCode+"/customer_info_data?page=0&size=10&expression=basicInfo.mobile+eq+" + "%s" + "&sort=basicInfo.registerTime,desc";
    static final String delete = baseUrl + "/gateway/api/member-manage/store/"+storeCode+"/customer_info_data/credential/%s";
    static final String unbinding = baseUrl + "/gateway/api/member-manage/store/"+storeCode+"/data_lake/customer/unbind/%s";


    static final String secretKey = "cBXC1FyQ8//pCLfWhIFwpw==";

    @SneakyThrows
    public static void main(String[] args) {
        PIIDataAESEncoder dataAESEncoder = new PIIDataAESEncoder(secretKey);
        CopyOnWriteArrayList<String> customerIds = new CopyOnWriteArrayList<>();
        CopyOnWriteArrayList<String> emptyCodes = new CopyOnWriteArrayList<>();
        log.info("【会员解绑】获取会员ID");
        ConcurrentHashMap<String, String> customerIdToThiCode = getCustomerIds(file, dataAESEncoder, customerIds, emptyCodes);

        FileUtil.writeString(JSONUtil.toJsonStr(customerIds), hit, Charset.defaultCharset());
        FileUtil.writeString(JSONUtil.toJsonStr(emptyCodes), empty, Charset.defaultCharset());
        FileUtil.writeString(JSONUtil.toJsonStr(customerIdToThiCode), codeMap, Charset.defaultCharset());

        log.info("【会员解绑】获取完毕，customerIds->{},emptyCodes->{}", customerIds.size(), emptyCodes.size());

        CopyOnWriteArrayList<String> errorUnbindingIds = new CopyOnWriteArrayList<>();
        CopyOnWriteArrayList<String> errorDeleteIds = new CopyOnWriteArrayList<>();
        List<Runnable> runnables = new ArrayList<>();
        for (String customerId : customerIds) {
            runnables.add(() -> {
                unbinding(token, errorUnbindingIds, customerId);
                delete(token, errorDeleteIds, customerId);
            });
        }
        log.info("【会员解绑】 即将执行会员解绑与删除 任务数->{}", runnables.size());
        if (CollUtil.isNotEmpty(runnables)) {
            ConcurrentUtil.commit(runnables);
        }

        FileUtil.writeString(JSONUtil.toJsonStr(errorUnbindingIds), unbindingErr, Charset.defaultCharset());
        FileUtil.writeString(JSONUtil.toJsonStr(errorDeleteIds), deleteErr, Charset.defaultCharset());
        log.info("【会员解绑】 解绑完成 解绑失败->{},删除失败->{}", errorUnbindingIds.size(), errorDeleteIds.size());

    }

    private static void delete(String token, CopyOnWriteArrayList<String> errorDeleteIds, String customerId) {
        try {
            String url = String.format(delete, customerId);
            HttpResponse response = HttpRequest.delete(url).header("Authorization", token).execute();
            int status = response.getStatus();
            if (status != 200) {
                log.error(response.body());
                errorDeleteIds.add(customerId);
            }
        } catch (Exception e) {
            errorDeleteIds.add(customerId);
        }
    }

    private static void unbinding(String token, CopyOnWriteArrayList<String> errorUnbindingIds, String customerId) {
        try {
            String url = String.format(unbinding, customerId);
            HttpResponse response = HttpRequest.get(url).header("Authorization", token).execute();
            int status = response.getStatus();
            if (status != 200) {
                log.error(response.body());
                errorUnbindingIds.add(customerId);
            }
        } catch (Exception e) {
            System.out.println("出现异常");
            errorUnbindingIds.add(customerId);
        }
    }

    /**
     * 获取customerId
     *
     * @param customerIds 获取到的
     * @param emptyCodes  没获取到的
     */
    private static ConcurrentHashMap<String, String> getCustomerIds(String file, PIIDataAESEncoder dataAESEncoder, CopyOnWriteArrayList<String> customerIds, CopyOnWriteArrayList<String> emptyCodes) {
        ConcurrentHashMap<String, String> customerIdToThiCode = new ConcurrentHashMap<>();
        List<Runnable> list = new ArrayList<>();
        TransformCsvData.peekCsv(file, 0, x -> {
            list.add(() -> {
                JSONArray content = httpGet(String.format(getInfoUrlByThCode, x[0]));
                if (!content.isEmpty()) {
                    JSONObject user = content.getJSONObject(0);
                    String customerId = user.get("id", String.class);
                    customerIds.add(customerId);
                    customerIdToThiCode.put(customerId, x[0]);
                } else {
                    if (x.length > 1 && StrUtil.isNotBlank(x[1])) {
                        String phone = x[1];
                        try {
                            String encodePhone = dataAESEncoder.encode(phone);
                            JSONArray contentPhone = httpGet(String.format(getInfoByPhone, encodePhone));
                            if (contentPhone.isEmpty()) {
                                String notHaveItem = "phone:" + phone + "  thCode:" + x[0];
                                emptyCodes.add(notHaveItem);
                            } else {
                                JSONObject user = contentPhone.getJSONObject(0);
                                String customerId = user.get("id", String.class);
                                customerIds.add(customerId);
                                customerIdToThiCode.put(customerId, x[0]);

                            }
                        } catch (Exception e) {
                            e.printStackTrace();
                            log.error("【会员解绑】通过手机号查询用户异常 phone:{}  thCode:{}", phone, x[0]);
                        }
                    } else {
                        String notHaveItem = "thCode:" + x[0];
                        emptyCodes.add(notHaveItem);
                    }
                }
            });
        });
        log.info("【会员解绑】runnable准备完毕，任务数->{}", list.size());
        ConcurrentUtil.commit(list,32,1);
        return customerIdToThiCode;
    }

    private static JSONArray httpGet(String url) {
        HttpRequest request = HttpRequest.get(url).header("Authorization", token);
        String response = request.execute().body();
        JSONObject jsonObject = JSONUtil.parseObj(response);
        return jsonObject.getJSONArray("content");
    }
}
